﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Collections;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.Office.Server.Diagnostics;
using Microsoft.SharePoint.Administration;
using System.IO;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WebPartPages;

using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.Publishing;

namespace spdevstore.spreports
{
    [Cmdlet(VerbsCommon.Get, "rp.WebPartsInPages", SupportsShouldProcess = true)]
    public class GetWebPartsInPages : PSCmdlet
    {

        #region Parameters
        [Parameter(Position = 0,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter Scope - Farm, WebApplication, SiteCollection or Site ")]
        public string Scope;

        [Parameter(Position = 1,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter URL as per Scope")]
        public string Site;

        [Parameter(Position = 2,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "WebPartName")]
        public string WebPartName;

        [Parameter(Position = 3,
        ParameterSetName = "",
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = "Enter Folder Path to save SPReport")]
        public string ResultsPath;


        #endregion

        protected override void ProcessRecord()
        {
            StreamWriter streamWriter = null;
            String resultPath = String.Empty;
            String filename = String.Empty;
            filename = "rp.WebPartsInPages.csv";

            //Build File Path for Results
            resultPath = Path.Combine(ResultsPath, filename);

            //Create or open existing file using Stream writer class with UTF Encoding and Overwrite option
            streamWriter = new StreamWriter(resultPath, false, Encoding.UTF8);
            streamWriter.WriteLine("Web Application, Site Collection, Site URL, Site Name, WebPart Title, Page URL, Is Hidden, Type, WebPart ID");
           // streamWriter.WriteLine("WebPart Title, Web URL, Page URL, Is Hidden, Type");

            if (Scope == "Farm")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {

                    try
                    {
                        SPServiceCollection services = SPFarm.Local.Services;
                        foreach (SPService curService in services)
                        {
                            if (curService is SPWebService)
                            {
                                SPWebService currentwebservice = (SPWebService)curService;
                                foreach (SPWebApplication webapp in currentwebservice.WebApplications)
                                {

                                    SPSite sitecol = null;
                                    try
                                    {
                                        using (sitecol = new SPSite(Site))
                                        {
                                            foreach (SPSite site in webapp.Sites)
                                            {
                                                foreach (SPWeb subWeb in site.AllWebs)
                                                {
                                                    WebPartsInPages(subWeb, streamWriter, resultPath);
                                                    subWeb.Dispose();
                                                }
                                            }
                                        }
                                    }

                                    catch (Exception ex)
                                    {
                                         
                                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                                    }

                                }
                            }

                        }

                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }

            else if (Scope == "WebApplication")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite sitecol = null;
                    try
                    {
                        using (sitecol = new SPSite(Site))
                        {
                            foreach (SPSite site in sitecol.WebApplication.Sites)
                            {
                                foreach (SPWeb subWeb in site.AllWebs)
                                {
                                    WebPartsInPages(subWeb, streamWriter, resultPath);
                                    subWeb.Dispose();
                                }
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }
                });
            }

            else if (Scope == "SiteCollection")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite sitecol = null;
                    try
                    {
                        using (sitecol = new SPSite(Site))
                        {
                            foreach (SPWeb subWeb in sitecol.AllWebs)
                            {
                                WebPartsInPages(subWeb, streamWriter, resultPath);
                                subWeb.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }

            else if (Scope == "Site")
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPSite site = null;
                    try
                    {
                        using (site = new SPSite(Site))
                        {

                            SPWeb subWeb = site.OpenWeb();
                            WebPartsInPages(subWeb, streamWriter, resultPath);
                            subWeb.Dispose();
                        }

                    }
                    catch (Exception ex)
                    {
                         
                        ThrowTerminatingError(new ErrorRecord(ex, "0", ErrorCategory.NotSpecified, null));
                    }

                });
            }
            else
            {
                WriteObject(string.Empty);
                WriteObject(string.Format("Invalid Scope entered as Parameter. Please verify and run the script. Scope should be Farm/WebApplication"));

            }
            streamWriter.Close();
        }
        private void WebPartsInPages(SPWeb web, StreamWriter streamWriter, String resultPath)
        {
            try
            {
                SPList pagesList = null;

                try
                {
                    if (PublishingWeb.IsPublishingWeb(web))
                    {
                        PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
                        pagesList = publishingWeb.PagesList;

                        if (null != pagesList)
                        {
                            foreach (SPListItem page in pagesList.Items)
                            {
                                PublishingPage publishingPage = publishingWeb.GetPublishingPage(page.ID);
                                SPFile file = publishingPage.ListItem.File;
                                if (file.Name.EndsWith(".aspx"))
                                {
                                    FindWebPart(streamWriter, web, WebPartName, file);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                     
                }

                pagesList = null;
                try
                {
                    pagesList = web.Lists["Site Pages"];
                    if (null != pagesList)
                    {
                        SPListItemCollection pages = pagesList.Items;
                        foreach (SPListItem page in pages)
                        {
                            SPFile file = page.File;
                            if (file.Name.EndsWith(".aspx"))
                            {
                                FindWebPart(streamWriter, web, WebPartName, file);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                     
                }

                try
                {
                    SPFileCollection files = web.Files;
                    foreach (SPFile file in files)
                    {
                        if (file.Name.EndsWith(".aspx"))
                        {
                            FindWebPart(streamWriter, web, WebPartName, file);
                        }
                    }
                }
                catch (Exception ex)
                {
                     
                }
            }
            catch (Exception ex)
            {
                 
            }

        }

        private void FindWebPart(StreamWriter streamWriter, SPWeb web, string WebPartName, SPFile file)
        {
            using (SPLimitedWebPartManager mgr = file.GetLimitedWebPartManager(PersonalizationScope.Shared))
            {
                try
                {
                    SPLimitedWebPartCollection webparts = mgr.WebParts;

                    foreach (object obj in mgr.WebParts)
                    {
                        if (obj is Microsoft.SharePoint.WebPartPages.WebPart)
                        {
                            Microsoft.SharePoint.WebPartPages.WebPart wp = (Microsoft.SharePoint.WebPartPages.WebPart)obj;
                            if (WebPartName.ToUpper() == wp.Title.ToUpper())
                            {

                                //streamWriter.WriteLine("Web Application, Site Collection, Site URL, Site Name, WebPart Title, Web URL, Page URL, Is Hidden, Type");
                                streamWriter.WriteLine(web.Site.WebApplication.Name + "," + web.Site.RootWeb.Url + "," + web.Url + "," + web.Title + "," + wp.Title + "," + file.Url + "," + wp.Hidden.ToString() + "," + wp.GetType().ToString() + "," + wp.ID);
                            }
                        }

                        if (obj is System.Web.UI.WebControls.WebParts.WebPart)
                        {
                            System.Web.UI.WebControls.WebParts.WebPart wp = (System.Web.UI.WebControls.WebParts.WebPart)obj;
                            if (WebPartName.ToUpper() == wp.Title.ToUpper())
                            {
                                streamWriter.WriteLine(web.Site.WebApplication.Name + "," + web.Site.RootWeb.Url + "," + web.Url + "," + web.Title + "," + wp.Title + "," + file.Url + "," + wp.Hidden.ToString() + "," + wp.GetType().ToString() + "," + wp.ID);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                     
                }
                finally
                {
                    mgr.Web.Dispose();
                }
            }
        }
    }
}

